package com.oristartech.netty.server.handler;

import com.oristartech.netty.common.message.MessageBuilder;
import com.oristartech.netty.common.message.MessageType;
import com.oristartech.netty.server.starter.NettyClientPool;
import com.oristartech.netty.server.starter.NettyClientWrapper;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Optional;

/**
 ** 服务端注册通道处理
 ** ，收到客户端的注册请求后，直接添加到NettyClientChannel中，并把注册信息返回给客户端
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2020-03-05 15:59
 * @blame Team
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class NettyServerRegisterHandler extends ChannelInboundHandlerAdapter {

    /**
     ** 客户端通道连接池
     */
    @Resource
    NettyClientPool nettyClientPool;

    /**
     ** 读取数据处理，注册成功并缓存当前的客户端通道
     *
     * @param ctx 通道上下文
     * @param msg 读取到的数据
     * @throws Exception 处理过程中存在异常则抛出
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        MessageBuilder messageBuilder = MessageBuilder.of(msg);
        if(messageBuilder.isMessage(MessageType.REGISTER)){
            // 缓存客户端通道
            nettyClientPool.putClient(messageBuilder.getMessage().getTenantId(),
                    messageBuilder.getMessage().getCinemaCode(), ctx.channel());
            log.info("客户端[{}-{}]注册，当前数量[{}]", messageBuilder.getMessage().getTenantId(),
                    messageBuilder.getMessage().getCinemaCode(), nettyClientPool.getSize());
            ctx.channel().writeAndFlush(msg);
            return;
        }
        ctx.fireChannelRead(msg);
    }

    /**
     ** 客户端失去连接处理，清空缓存的客户端通道
     *
     * @param ctx 通道上下文
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Optional<NettyClientWrapper> clientOptional = nettyClientPool.getClient(ctx.channel());
        clientOptional.ifPresent(nettyClient -> {
            // 清空缓存的客户端通道
            nettyClientPool.removeClient(ctx.channel());
            log.info("客户端[{}-{}]退出，当前数量[{}]",
                    nettyClient.getTenantId(), nettyClient.getCinemaCode(), nettyClientPool.getSize());
        });
        ctx.fireChannelInactive();
    }
}
